package com.zbkj.crmeb.store.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.common.PageParamRequest;
import com.github.pagehelper.PageHelper;
import com.utils.DateUtil;
import com.utils.vo.dateLimitUtilVo;
import com.zbkj.crmeb.enums.OrderStatusEnum;
import com.zbkj.crmeb.store.dao.StoreOrderInfoDao;
import com.zbkj.crmeb.store.model.*;
import com.zbkj.crmeb.store.request.StoreOrderInfoActivityRequest;
import com.zbkj.crmeb.store.request.StoreOrderInfoSearchRequest;
import com.zbkj.crmeb.store.response.StoreCartResponse;
import com.zbkj.crmeb.store.response.StoreProductCartProductInfoResponse;
import com.zbkj.crmeb.store.service.*;
import com.zbkj.crmeb.store.vo.StoreOrderInfoVo;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
* @author Mr.Zhang
* @description StoreOrderInfoServiceImpl 接口实现
* @date 2020-05-28
*/
@Service
public class StoreOrderInfoServiceImpl extends ServiceImpl<StoreOrderInfoDao, StoreOrderInfo>
        implements StoreOrderInfoService {

    @Resource
    private StoreOrderInfoDao dao;

    @Autowired
    private StoreProductReplyService storeProductReplyService;

    @Autowired
    private StoreProductService storeProductService;
    @Autowired
    private StoreOrderInfoPickingService storeOrderInfoPickingService;
    @Autowired
    private StoreProductAttrValueService storeProductAttrValueService;


    /**
    * 列表
    * @param request 请求参数
    * @param pageParamRequest 分页类参数
    * @author Mr.Zhang
    * @since 2020-05-28
    * @return List<StoreOrderInfo>
    */
    @Override
    public List<StoreOrderInfo> getList(StoreOrderInfoSearchRequest request, PageParamRequest pageParamRequest) {
        PageHelper.startPage(pageParamRequest.getPage(), pageParamRequest.getLimit());

        //带 StoreOrderInfo 类的多条件查询
        LambdaQueryWrapper<StoreOrderInfo> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        StoreOrderInfo model = new StoreOrderInfo();
        BeanUtils.copyProperties(request, model);
        lambdaQueryWrapper.setEntity(model);
        return dao.selectList(lambdaQueryWrapper);
    }

    /**
     * 根据id集合查询数据，返回 map
     * @param orderList List<Integer> id集合
     * @author Mr.Zhang
     * @since 2020-04-17
     * @return HashMap<Integer, StoreCart>
     */
    @Override
    public HashMap<Integer, List<StoreOrderInfoVo>> getMapInId(List<Integer> orderList){
        HashMap<Integer, List<StoreOrderInfoVo>> map = new HashMap<>();
        if(orderList.size() < 1){
            return map;
        }
        LambdaQueryWrapper<StoreOrderInfo> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.in(StoreOrderInfo::getOrderId, orderList);
        List<StoreOrderInfo> systemStoreStaffList = dao.selectList(lambdaQueryWrapper);
        if(systemStoreStaffList.size() < 1){
            return map;
        }
        for (StoreOrderInfo storeOrderInfo : systemStoreStaffList) {
            //解析商品详情JSON
            StoreOrderInfoVo StoreOrderInfoVo = new StoreOrderInfoVo();
            BeanUtils.copyProperties(storeOrderInfo, StoreOrderInfoVo, "info");
            StoreOrderInfoVo.setInfo(JSON.parseObject(storeOrderInfo.getInfo(), StoreCartResponse.class));
            if(map.containsKey(storeOrderInfo.getOrderId())){
                map.get(storeOrderInfo.getOrderId()).add(StoreOrderInfoVo);
            }else{
                List<StoreOrderInfoVo> storeOrderInfoVoList = new ArrayList<>();
                storeOrderInfoVoList.add(StoreOrderInfoVo);
                map.put(storeOrderInfo.getOrderId(), storeOrderInfoVoList);
            }
        }
        return map;
    }

    @Override
    public HashMap<Integer, List<StoreOrderInfoVo>> getMapInIdWaitForComplete(List<Integer> orderIdList) {
        HashMap<Integer, List<StoreOrderInfoVo>> map = new HashMap<>();
        if(orderIdList.size() < 1){
            return map;
        }
        LambdaQueryWrapper<StoreOrderInfo> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.in(StoreOrderInfo::getOrderId, orderIdList);
        lambdaQueryWrapper.eq(StoreOrderInfo::getStatus, OrderStatusEnum.SHIPPED.getCode());
        List<StoreOrderInfo> systemStoreStaffList = dao.selectList(lambdaQueryWrapper);
        if(systemStoreStaffList.size() < 1){
            return map;
        }
        for (StoreOrderInfo storeOrderInfo : systemStoreStaffList) {
            //解析商品详情JSON
            StoreOrderInfoVo StoreOrderInfoVo = new StoreOrderInfoVo();
            BeanUtils.copyProperties(storeOrderInfo, StoreOrderInfoVo, "info");
            StoreOrderInfoVo.setInfo(JSON.parseObject(storeOrderInfo.getInfo(), StoreCartResponse.class));
            if(map.containsKey(storeOrderInfo.getOrderId())){
                map.get(storeOrderInfo.getOrderId()).add(StoreOrderInfoVo);
            }else{
                List<StoreOrderInfoVo> storeOrderInfoVoList = new ArrayList<>();
                storeOrderInfoVoList.add(StoreOrderInfoVo);
                map.put(storeOrderInfo.getOrderId(), storeOrderInfoVoList);
            }
        }
        return map;
    }

    /**
     * 根据id集合查询数据，返回 map
     * @param orderId Integer id
     * @author Mr.Zhang
     * @since 2020-04-17
     * @return HashMap<Integer, StoreCart>
     */
    @Override
    public List<StoreOrderInfoVo> getOrderListByOrderId(Integer orderId){
        LambdaQueryWrapper<StoreOrderInfo> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(StoreOrderInfo::getOrderId, orderId);
        List<StoreOrderInfo> systemStoreStaffList = dao.selectList(lambdaQueryWrapper);
        if(systemStoreStaffList.size() < 1){
            return null;
        }

        List<StoreOrderInfoVo> storeOrderInfoVoList = new ArrayList<>();
        for (StoreOrderInfo storeOrderInfo : systemStoreStaffList) {
            StoreProduct product = Optional.ofNullable(storeProductService.getOne(Wrappers.lambdaQuery(StoreProduct.class).eq(StoreProduct::getId, storeOrderInfo.getProductId()))).orElse(new StoreProduct());
            //解析商品详情JSON
            StoreOrderInfoVo StoreOrderInfoVo = new StoreOrderInfoVo();
            BeanUtils.copyProperties(storeOrderInfo, StoreOrderInfoVo, "info");
            StoreCartResponse storeCartResponse = JSON.parseObject(storeOrderInfo.getInfo(), StoreCartResponse.class);
            StoreOrderInfoVo.setInfo(storeCartResponse);
            StoreOrderInfoVo.getInfo().setIsReply(
                    storeProductReplyService.isReply(StoreOrderInfoVo.getUnique(),"product",StoreOrderInfoVo.getOrderId()).size()
            );
            StoreOrderInfoVo.getInfo().getProductInfo().setSupplierName(product.getSuppliersName());
            StoreOrderInfoVo.setActualTaxAndSecondPrice(storeOrderInfo.getTaxTaxesPrice()
                    .add(storeOrderInfo.getTaxInlandDeliveryPrice())
                    .add(storeOrderInfo.getTaxInternationalPrice())
                    .add(storeOrderInfo.getTaxTurnInlandPrice()));
            StoreOrderInfoVo.setNum(1);
            //当前库存
            StoreProductAttrValue attrValue = Optional.ofNullable(storeProductAttrValueService.getOne(Wrappers.lambdaQuery(StoreProductAttrValue.class).eq(StoreProductAttrValue::getSourceSkuId, storeCartResponse.getProductInfo().getAttrInfo().getSourceSkuId())
                    .eq(StoreProductAttrValue::getProductId, storeOrderInfo.getProductId()).last("LIMIT 1"))).orElse(new StoreProductAttrValue());
            StoreOrderInfoVo.setStock(attrValue.getStock());
            StoreProductCartProductInfoResponse productInfo = storeCartResponse.getProductInfo();
            if (null!= productInfo && productInfo.getAttrInfo()!=null){
                productInfo.getAttrInfo().setSelfSourceSkuId(attrValue.getSelfSourceSkuId());
            }
            storeOrderInfoVoList.add(StoreOrderInfoVo);
        }
        return storeOrderInfoVoList;
    }

    @Override
    public List<StoreOrderInfoVo> getPickingOrderListByOrderId(Integer orderId){
        List<StoreOrderInfoVo> storeOrderInfoVoList = new ArrayList<>();
        LambdaQueryWrapper<StoreOrderInfoPicking> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(StoreOrderInfoPicking::getOrderId, orderId);
        lambdaQueryWrapper.eq(StoreOrderInfoPicking::getIsDel, 0);
        List<StoreOrderInfoPicking> systemStoreStaffList = storeOrderInfoPickingService.list(lambdaQueryWrapper);
        if(systemStoreStaffList.size() < 1){
            return storeOrderInfoVoList;
        }

        for (StoreOrderInfoPicking storeOrderInfo : systemStoreStaffList) {
            StoreProduct product = Optional.ofNullable(storeProductService.getOne(Wrappers.lambdaQuery(StoreProduct.class).eq(StoreProduct::getId, storeOrderInfo.getProductId()))).orElse(new StoreProduct());
            //解析商品详情JSON
            StoreOrderInfoVo StoreOrderInfoVo = new StoreOrderInfoVo();
            BeanUtils.copyProperties(storeOrderInfo, StoreOrderInfoVo, "info");
            StoreCartResponse storeCartResponse = JSON.parseObject(storeOrderInfo.getInfo(), StoreCartResponse.class);
            StoreOrderInfoVo.setInfo(storeCartResponse);
            StoreOrderInfoVo.getInfo().setIsReply(
                    storeProductReplyService.isReply(StoreOrderInfoVo.getUnique(),"product",StoreOrderInfoVo.getOrderId()).size()
            );
            StoreOrderInfoVo.getInfo().getProductInfo().setSupplierName(product.getSuppliersName());
            StoreOrderInfoVo.setNum(storeOrderInfo.getNum());
            //当前库存
            StoreProductAttrValue attrValue = Optional.ofNullable(storeProductAttrValueService.getOne(Wrappers.lambdaQuery(StoreProductAttrValue.class).eq(StoreProductAttrValue::getSourceSkuId, storeCartResponse.getProductInfo().getAttrInfo().getSourceSkuId())
                    .eq(StoreProductAttrValue::getProductId, storeOrderInfo.getProductId()).last("LIMIT 1"))).orElse(new StoreProductAttrValue());
            StoreOrderInfoVo.setStock(attrValue.getStock());
            StoreOrderInfoVo.setIsVirtual(true);
            StoreProductCartProductInfoResponse productInfo = storeCartResponse.getProductInfo();
            if (null!= productInfo && productInfo.getAttrInfo()!=null){
                productInfo.getAttrInfo().setSelfSourceSkuId(attrValue.getSelfSourceSkuId());
            }
            storeOrderInfoVoList.add(StoreOrderInfoVo);
        }
        return storeOrderInfoVoList;
    }

    @Override
    public List<StoreOrderInfoVo> getOrderListByOrderIdTwo(Integer orderId){
        LambdaQueryWrapper<StoreOrderInfo> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(StoreOrderInfo::getOrderId, orderId);
        lambdaQueryWrapper.eq(StoreOrderInfo::getStatus,6);
        List<StoreOrderInfo> systemStoreStaffList = dao.selectList(lambdaQueryWrapper);
        List<StoreOrderInfoVo> storeOrderInfoVoList = new ArrayList<>();
        if(systemStoreStaffList.size() < 1){
            return storeOrderInfoVoList;
        }

        for (StoreOrderInfo storeOrderInfo : systemStoreStaffList) {
            StoreProduct product = Optional.ofNullable(storeProductService.getOne(Wrappers.lambdaQuery(StoreProduct.class)
            		.eq(StoreProduct::getId, storeOrderInfo.getProductId())
            		)
            		).orElse(new StoreProduct());
            //解析商品详情JSON
            StoreOrderInfoVo StoreOrderInfoVo = new StoreOrderInfoVo();
            BeanUtils.copyProperties(storeOrderInfo, StoreOrderInfoVo, "info");
            // TODO didiok
            StoreOrderInfoVo.setInfo(JSON.parseObject(storeOrderInfo.getInfo(), StoreCartResponse.class));
            StoreOrderInfoVo.getInfo().setIsReply(
                    storeProductReplyService.isReply(StoreOrderInfoVo.getUnique(), "product", StoreOrderInfoVo.getOrderId()).size()
            );
            StoreOrderInfoVo.getInfo().getProductInfo().setSupplierName(product.getSuppliersName());
            storeOrderInfoVoList.add(StoreOrderInfoVo);
        }
        return storeOrderInfoVoList;
    }

    @Override
    public List<StoreOrderInfo> getChildOrderGroupByDate(String date, int lefTime,Integer merId) {
        QueryWrapper<StoreOrderInfo> queryWrapper = new QueryWrapper<>();
        queryWrapper.select("sum(pay_price+deduction_price) as pay_price", "left(create_time, "+lefTime+") as childOrderNumber", "count(id) as id");
        if(StringUtils.isNotBlank(date)){
            dateLimitUtilVo dateLimit = DateUtil.getDateLimit(date);
            queryWrapper.between("create_time", dateLimit.getStartTime(), dateLimit.getEndTime());
        }
        queryWrapper.ne("status",0).ne("status",5)
                .inSql(merId != null,"order_id","select id from eb_store_order where mer_id = " + merId);
        queryWrapper.groupBy("childOrderNumber").orderByAsc("childOrderNumber");
        return dao.selectList(queryWrapper);
    }

    @Override
    public int getChildOrderCount(String date,Integer merId) {
        LambdaQueryWrapper<StoreOrderInfo> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.ne(StoreOrderInfo::getStatus,0).ne(StoreOrderInfo::getStatus,5)
                .inSql(merId != null,StoreOrderInfo::getOrderId,"select id from eb_store_order where mer_id = " + merId);
        if(StringUtils.isNotBlank(date)){
            dateLimitUtilVo dateLimit = DateUtil.getDateLimit(date);
            lambdaQueryWrapper.between(StoreOrderInfo::getCreateTime, dateLimit.getStartTime(), dateLimit.getEndTime());
        }
        return dao.selectCount(lambdaQueryWrapper);
    }

    @Override
    public BigDecimal getSumBigDecimal(String date,Integer merId) {
        QueryWrapper<StoreOrderInfo> queryWrapper = new QueryWrapper<>();
        queryWrapper.select("sum(pay_price+deduction_price) as pay_price")
                .ne("status",0).ne("status",5)
                .inSql(merId != null,"order_id","select id from eb_store_order where mer_id = " + merId);
        if(null != date){
            dateLimitUtilVo dateLimit = DateUtil.getDateLimit(date);
            queryWrapper.between("create_time", dateLimit.getStartTime(), dateLimit.getEndTime());
        }
        StoreOrderInfo storeOrderInfo = dao.selectOne(queryWrapper);
        if(null == storeOrderInfo || null == storeOrderInfo.getPayPrice()){
            return BigDecimal.ZERO;
        }
        return storeOrderInfo.getPayPrice();
    }

    /**
     * 新增订单详情
     * @param storeOrderInfos 订单详情集合
     * @return 订单新增结果
     */
    @Override
    public boolean saveOrderInfos(List<StoreOrderInfo> storeOrderInfos) {
        return saveBatch(storeOrderInfos);
    }

    @Override
    public List<StoreOrderInfo> getStoreOrderInfoList(Integer productId) {
        return dao.getStoreOrderInfoList(productId);
    }

    @Override
    public List<StoreOrderInfo> getStoreOrderInfoListUnPaid(List<Integer> productIdList, List<Integer> activityIds) {
        return dao.getStoreOrderInfoListUnPaid(productIdList, activityIds);
    }

    @Override
    public List<StoreOrderInfo> getUserOrderList(StoreOrder storeOrderPram) {
        return dao.getUserOrderList(storeOrderPram);
    }

    @Override
    public List<StoreOrderInfo> getOrderCount(StoreOrder storeOrderPram) {
        return dao.getOrderCount(storeOrderPram);
    }

    /**
     * 统计订单金额
     *
     * @param searchDateDay
     * @param merIds
     * @return
     */
    @Override
    public BigDecimal getSumBigDecimalByMerIds(String searchDateDay, List<Integer> merIds) {
        String merIdList = "(" + merIds.stream().map(String::valueOf).collect(Collectors.joining(",")) + ")";
        QueryWrapper<StoreOrderInfo> queryWrapper = new QueryWrapper<>();
        queryWrapper.select("sum(pay_price+deduction_price) as pay_price")
                .ne("status", 0)
                .ne("status", 5)
                .inSql(CollectionUtils.isNotEmpty(merIds),"order_id", "select id from eb_store_order where mer_id in " + merIdList);
        if (StringUtils.isNotBlank(searchDateDay)) {
            dateLimitUtilVo dateLimit = DateUtil.getDateLimit(searchDateDay);
            queryWrapper.between("create_time", dateLimit.getStartTime(), dateLimit.getEndTime());
        }
        StoreOrderInfo storeOrderInfo = dao.selectOne(queryWrapper);
        if (Objects.isNull(storeOrderInfo) || Objects.isNull(storeOrderInfo.getPayPrice())) {
            return BigDecimal.ZERO;
        }
        return storeOrderInfo.getPayPrice();
    }

    /**
     * 订单量
     * @param searchDateDay  搜索日期
     * @param merIds 商户ids
     * @return
     */
    @Override
    public Integer countChildOrderByMerIds(String searchDateDay, List<Integer> merIds) {
        String merIdList = "(" + merIds.stream().map(String::valueOf).collect(Collectors.joining(",")) + ")";
        LambdaQueryWrapper<StoreOrderInfo> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.ne(StoreOrderInfo::getStatus,0)
                .ne(StoreOrderInfo::getStatus,5)
                .inSql(CollectionUtils.isNotEmpty(merIds),StoreOrderInfo::getOrderId,"select id from eb_store_order where mer_id in " + merIdList);
        if(StringUtils.isNotBlank(searchDateDay)){
            dateLimitUtilVo dateLimit = DateUtil.getDateLimit(searchDateDay);
            lambdaQueryWrapper.between(StoreOrderInfo::getCreateTime, dateLimit.getStartTime(), dateLimit.getEndTime());
        }
        return dao.selectCount(lambdaQueryWrapper);
    }

    /**
     * 订单量统计
     * @param date
     * @param lefTime
     * @param merIds
     * @return
     */
    @Override
    public List<StoreOrderInfo> sumChildOrderGroupByDate(String date, int lefTime, List<Integer> merIds) {
        String merIdList = "(" + merIds.stream().map(String::valueOf).collect(Collectors.joining(",")) + ")";
        QueryWrapper<StoreOrderInfo> queryWrapper = new QueryWrapper<>();
        queryWrapper.select("sum(pay_price+deduction_price) as pay_price", "left(create_time, "+lefTime+") as childOrderNumber", "count(id) as id");
        if(StringUtils.isNotBlank(date)){
            dateLimitUtilVo dateLimit = DateUtil.getDateLimit(date);
            queryWrapper.between("create_time", dateLimit.getStartTime(), dateLimit.getEndTime());
        }

        queryWrapper.ne("status",0).ne("status",5)
                .inSql(CollectionUtils.isNotEmpty(merIds),"order_id","select id from eb_store_order where mer_id in " + merIdList);
        queryWrapper.groupBy("childOrderNumber").orderByAsc("childOrderNumber");
        return dao.selectList(queryWrapper);
    }

    /**
     * 净利润统计
     *
     * @param searchDateDay
     * @param merIds
     * @param field
     * @return
     */
    @Override
    public BigDecimal getSumProfitBigDecimal(String searchDateDay, List<Integer> merIds, String field) {
        String merIdList = "(" + merIds.stream().map(String::valueOf).collect(Collectors.joining(",")) + ")";
        QueryWrapper<StoreOrderInfo> queryWrapper = new QueryWrapper<>();
        queryWrapper.select("sum(" + field + ") as pay_price")
                .ne("status", 0)
                .ne("status", 5)
                .inSql(CollectionUtils.isNotEmpty(merIds),"order_id", "select id from eb_store_order where mer_id in " + merIdList);
        if (StringUtils.isNotBlank(searchDateDay)) {
            dateLimitUtilVo dateLimit = DateUtil.getDateLimit(searchDateDay);
            queryWrapper.between("create_time", dateLimit.getStartTime(), dateLimit.getEndTime());
        }
        StoreOrderInfo storeOrderInfo = dao.selectOne(queryWrapper);
        if (Objects.isNull(storeOrderInfo) || Objects.isNull(storeOrderInfo.getPayPrice())) {
            return BigDecimal.ZERO;
        }
        return storeOrderInfo.getPayPrice();
    }

    /**
     * 批量查询订单实付金额
     * @param orders
     * @return java.math.BigDecimal
     */
    @Override
    public BigDecimal getOrderPaidAmount(List<String> orders) {
        List<StoreOrderInfo> storeOrderInfos = dao.selectList(new LambdaQueryWrapper<>(StoreOrderInfo.class).in(StoreOrderInfo::getChildOrderNumber, orders));
        return storeOrderInfos.stream().map(StoreOrderInfo::getPayPrice).reduce(BigDecimal.ZERO,BigDecimal::add);
    }

    @Override
    public Integer getNumByActivityId(StoreOrderInfoActivityRequest request) {
        return dao.getNumByActivityId(request);
    }

    @Override
    public List<StoreOrderInfo> getUnionAllOrderInfo(StoreOrder storeOrderPram) {
        return dao.getUnionAllOrderInfo(storeOrderPram);
    }

    @Override
    public List<StoreOrderInfo> getVerifyOrderInfo(StoreOrder storeOrderPram) {
        return dao.getVerifyOrderInfo(storeOrderPram);
    }
}

